/*
 * Copyright (c) 2011, Julien Lamy
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the name of the project's author nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef ff1f87b4_1cfb_478a_af33_4afe9ef38737
#define ff1f87b4_1cfb_478a_af33_4afe9ef38737

#include <iostream>
#include <string>

#include "config.h"

/** @brief Logging functionalities. */
namespace logging
{

/** @brief Log level, in order of descending importance. */
enum Level
{
    CRITICAL,
    ERROR,
    WARNING,
    INFO,
    DEBUG,

};

/** @brief Convert a log level to its string representation. */
BABELPOD_EXPORT std::string to_string(Level lvl);

/** @brief Current log level. */
BABELPOD_EXPORT extern Level level;

/** @brief Log message, irrespective of log level. */
BABELPOD_EXPORT std::ostream & log(Level lvl, std::ostream & stream=std::cout);

/** @brief Log message, irrespective of log level. */
BABELPOD_EXPORT std::ostream & log(Level lvl, std::string const & file, int line, std::ostream & stream=std::cout);

}

/**
 * @brief Display a log message if the given level is above logging::level.
 *
 * Functions with side effects should not be use in log messages : if log
 * level is not high enough, they will not be called.
 */
#define BABELPOD_LOG(lvl) \
    if(::logging::level < ::logging::lvl) {} \
    else ::logging::log(::logging::lvl)

/**
 * @brief Display a log message if the given level if above logging::level,
 * add file name and line number to message.
 *
 * Functions with side effects should not be use in log messages : if log
 * level is not high enough, they will not be called.
 */
#define BABELPOD_LOG_VERBOSE(lvl) \
    if(::logging::level < ::logging::lvl) {} \
    else ::logging::log(::logging::lvl, __FILE__, __LINE__)

/**
 * @brief Display a log message on a user-defined stream if the given level
 * is above logging::level.
 *
 * Functions with side effects should not be use in log messages : if log
 * level is not high enough, they will not be called.
 */
#define BABELPOD_LOG_STREAM(lvl, stream) \
    if(::logging::level < ::logging::lvl) {} \
    else ::logging::log(::logging::lvl, stream)

/**
 * @brief Display a log message on a user-defined stream if the given level
 * is above logging::level, add file name and line number to message.
 *
 * Functions with side effects should not be use in log messages : if log
 * level is not high enough, they will not be called.
 */
#define BABELPOD_LOG_VERBOSE_STREAM(lvl, stream) \
    if(::logging::level < ::logging::lvl) {} \
    else ::logging::log(::logging::lvl, __FILE__, __LINE__, stream)

#endif // ff1f87b4_1cfb_478a_af33_4afe9ef38737
